/************************************
 文件明 ：  bsp_epit_timer.c
 作者   ：  胡秋峰
 描述   ：  EPIT定时器驱动文件
 ************************************/
#include "bsp_epit_timer.h"
#include "bsp_int.h"
#include "bsp_led.h"

/**
 * @描述            ： 初始化EPIT定时器
 *                     EPIT定时器是32位向下计数器，时钟源使用ipg=66MHZ
 * @参数 - frac     ： 分频值 0~4095->1~4096分频
 * @参数 - value    ： 加载寄存器值
 * @返回值  ： 无 
 */
void epit1_init(uint32_t frac, uint32_t value)
{
    if (frac > 0xFFF) {
        frac = 0XFFF;
    }
    EPIT1->CR = 0;

    /**
     * CR寄存器：
     * [25:24]  01      时钟源选择Peripheral clock = 66MHZ
     * [15:4]   frac    分频值
     * [3]      1       当计数器到0的话，从LR寄存器重新加载数值
     * [2]      1       比较中断使能
     * [1]      1       初始计数值来源于LR寄存器
     * [0]      0       先关闭EPIT1
     */ 
    EPIT1->CR = (0x1 << 24) |
                (frac << 4) |
                (1 << 3) | 
                (1 << 2) | 
                (1 << 1) | 
                (0 << 0);
    EPIT1->LR = value; /* 加载寄存器 */
    EPIT1->CMPR = 0; /* 比较寄存器 */

    /* 使能GIC对应中断 */
    GIC_EnableIRQ(EPIT1_IRQn);
    /* 注册中断服务函数 */
    system_register_irq_handler(EPIT1_IRQn, 
                                (system_irq_handler_t)epit1_irq_handler,
                                NULL);
    EPIT1->CR |= (1 << 0); /* 使能EPIT1 */
}


/**
 * @描述    ： 中断处理函数
 * @参数    ： 无
 * @返回值  ： 无 
 */
void epit1_irq_handler(void)
{
    static uint8_t state = 0;
    state = !state;

    if (EPIT1->SR & (1 << 0)) { /* 判断比较事件发生 */
        led_switch(LED0, state);
    }
    EPIT1->SR |= (1 << 0);  /* 清除中断标志位 */
}